package geppetto.cat.models.stats;

import geppetto.cat.constrains.ConstrainedProjectionStats;

//TODO What is this class good for. I think i have code to do this that should be merged into this class. see how this workd.

/**
 * Container for statisics on the E-Step
 * 
 * @author Kuzman
 * 
 * 
 */
public class EStepStats {
	public double logLikelihood = 0.0;
	public int numSents = 0;
	int numZeroLikelihood = 0;
	double totalLikelihood = 0;
	int[] zeroLikelihoodSentenceLen = new int[5];
	long start = -1;
	long total = 0;
	
	public ConstrainedProjectionStats pstats = null;
	
	
	static java.text.DecimalFormat fmt = new java.text.DecimalFormat();

	public void add(EStepStats other) {
		logLikelihood += other.logLikelihood;
		numSents += other.numSents;
		pstats = other.pstats;
	}

	
	public void add(SentenceEStepStats sentenceStats, int sourceSize) {
//		if(sentenceStats.loglikelihood < 1.0e-200){
//			numZeroLikelihood++;
//			if (numZeroLikelihood < zeroLikelihoodSentenceLen.length){
//				zeroLikelihoodSentenceLen[numZeroLikelihood] = sourceSize;
//			}
//		}else{
			logLikelihood += sentenceStats.loglikelihood;
//		}
		numSents ++;
		
		if(sentenceStats.pstats != null && pstats != null){
				pstats.add(sentenceStats.pstats);
		}
	}
	
	public void startTime() {
		start = System.currentTimeMillis();
	}

	public void stopTime() {
		total += System.currentTimeMillis() - start;
	}

	public String makeVerbose(EStepStats prev) {
		StringBuffer s = new StringBuffer();
		s.append("\t-log(L)=" + prettyPrint(-logLikelihood, "0.000E00", 9));
		s.append(" diff="+ prettyPrint(logLikelihood - prev.logLikelihood,"0.000E00", 9));
		s.append(" time=" + formatTime(total));
		if(numZeroLikelihood > 0){
			s.append("\n");
			s.append("Numerical underflow happened "+ numZeroLikelihood + " times " + "First few are ");
			for (int i : zeroLikelihoodSentenceLen) {
				s.append(i + " ");
			}
		}
		if(pstats != null){
			s.append(pstats.prettyPrint());
		}
		return s.toString();
	}

	public static String formatTime(long duration) {
		StringBuilder sb = new StringBuilder();
		double d = duration / 1000;
		fmt.applyPattern("00");
		sb.append(fmt.format((int) (d / (60 * 60))) + ":");
		d -= ((int) d / (60 * 60)) * 60 * 60;
		sb.append(fmt.format((int) (d / 60)) + ":");
		d -= ((int) d / 60) * 60;
		fmt.applyPattern("00.0");
		sb.append(fmt.format(d));
		return sb.toString();
	}

	public static String prettyPrint(double d, String patt, int len) {
		fmt.applyPattern(patt);
		String s = fmt.format(d);
		while (s.length() < len) {
			s = " " + s;
		}
		return s;
	}

}
